import globalConfig from '@/core/framework/config/globalConfig'
import useAppTokenInfoStore from '@/core/application/store/useAppTokenInfoStore'
import lodash from 'lodash'
import Oauth2TokenInfoDto from '@/core/oauth2/types/model/dto/Oauth2TokenInfoDto'
import oauth2Manager from '@/core/oauth2/manager/oauth2Manager'
import treeUtils from '@/core/utils/treeUtils'
import AppApplicationResponse from '@/core/application/types/model/response/AppApplicationResponse'
import debounceUtils from '@/core/utils/debounceUtils'
import appApplicationServerApi from '@/core/application/serverapi/appApplicationServerApi'
import authManager from '@/core/auth/manager/authManager'
import promiseUtils from '@/core/utils/promiseUtils'

class AppService {
	getByIdsWithDebounce: (id: string) => Promise<AppApplicationResponse[]> = debounceUtils.define<
		string,
		AppApplicationResponse[]
	>((ids: string[]): Promise<AppApplicationResponse[]> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		return promiseUtils.ofResponse(appApplicationServerApi.getByIds(userAccessToken, ids)).check()
	})

	init = async (): Promise<void> => {
		treeUtils.arrayToTree([], null)
		this.refreshToken()
	}

	refreshToken = async (): Promise<void> => {
		const appTokenInfo = useAppTokenInfoStore.getState()
		const isValidAppTokenByServer = await this.isValidAppTokenByServer(appTokenInfo)
		if (isValidAppTokenByServer) {
			return
		}
		this.initAppTokenInfo()
	}

	initAppTokenInfo = async (): Promise<void> => {
		const appTokenInfo = await oauth2Manager.getTokenByClientGrantType(globalConfig.clientId, globalConfig.clientSecret)
		useAppTokenInfoStore.setState(appTokenInfo)
	}

	isValidAppTokenByServer = async (appToken: Oauth2TokenInfoDto): Promise<boolean> => {
		if (lodash.isNil(appToken?.accessToken)) {
			return false
		}
		const tokenActive = await oauth2Manager.validTokenActive(
			appToken.accessToken,
			globalConfig.clientId,
			globalConfig.clientSecret,
		)
		return tokenActive
	}
}

export default new AppService()
